package com.sunchis.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.util.HashMap;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

public class MyHttpClientManager {
	private static final String Tag = MyHttpClientManager.class.getSimpleName();
	
	private HashMap<String, SoftReference<Bitmap>> imageBitmapCache;
	
	public static String cacheDir  = Environment.getExternalStorageDirectory().getAbsolutePath() + "/sunchis/";
	
	public MyHttpClientManager() {
		imageBitmapCache = new HashMap<String, SoftReference<Bitmap>>();
	}
	
	public interface ImageBitmapCallback {
        public void imageLoaded(Bitmap bitmap, String imageUrl);
    }
	
	/**
     * 生成或获取缓存图片的图片名称
     * @param imageUrl 图片URL
     * @return
     */
    public static String getImageName(String imageUrl) {
    	int position = imageUrl.lastIndexOf("/");
    	return imageUrl.substring(position + 1);
    }
	
	/**
	 * 从网络下载图片，若SD卡缓存中存在，则从缓存中直接读取
	 * @param imageUrl
	 * @return
	 */
	public Bitmap performGetBitmapImage(String imageUrl) {
		Bitmap bitmap = null;
		if(!checkImageUrl(imageUrl)) return null;
		
		bitmap = getBitmapFromSDCache(imageUrl);
		if (bitmap != null) {
			Log.d(Tag, "从SD卡缓存中读取图片成功");
			return bitmap;
		}
		
		InputStream inputStream = null;
		try {
			inputStream = downloadImageStream(imageUrl);
			cacheToSdCard(imageUrl, inputStream);
		} finally {
			try {
				if (inputStream != null) {
					inputStream.close();
				}
			} catch (IOException e) {
				Log.e(Tag, "I/O error while retrieving bitmap from " + imageUrl, e);
			}
		}
		
		bitmap = getBitmapFromSDCache(imageUrl);
		return bitmap;
	}
	
	/**
	 * 异步方式加载网络图片 (Bitmap)
	 * @param imageUrl
	 * @param imageBitmapCallback
	 * @return
	 */
	public Bitmap asyncLoadImageBitmap(final String imageUrl, final ImageBitmapCallback imageBitmapCallback) {
		if (imageBitmapCache.containsKey(imageUrl)) {
            SoftReference<Bitmap> softReference = imageBitmapCache.get(imageUrl);
            Bitmap bitmap = softReference.get();
            if (bitmap != null) {
                return bitmap;
            }
        }
		final Handler handler = new Handler() {
            public void handleMessage(Message message) {
            	imageBitmapCallback.imageLoaded((Bitmap) message.obj, imageUrl);
            }
        };
        new Thread() {
            @Override
            public void run() {
            	Bitmap bitmap = performGetBitmapImage(imageUrl);
            	imageBitmapCache.put(imageUrl, new SoftReference<Bitmap>(bitmap));
                Message message = handler.obtainMessage(0, bitmap);
                handler.sendMessage(message);
            }
        }.start();
        return null;
	}
	
	/**
	 * 图片对应URL的合法性检查
	 * @param imageUrl
	 * @return
	 */
	private boolean checkImageUrl(String imageUrl) {
		if (imageUrl == null) {
			Log.e(Tag, "图片地址为null，程序异常");
			return false;
		}
		if (imageUrl.equals("")) {
			Log.e(Tag, "图片地址为空，程序异常");
			return false;
		}
		return true;
	}
    
    /**
     * HttpClient方式下载图片
     * @param imageUrl
     * @return
     */
    private InputStream downloadImageStream(String imageUrl) {
    	InputStream inputStream = null;
		DefaultHttpClient client = new DefaultHttpClient();
		
		long t1 = System.currentTimeMillis();
		HttpGet getRequest = new HttpGet(imageUrl);	// 创建HttpGet连接对象
		
		try {
			//请求httpClient ，取得HttpRestponse
			HttpResponse response = client.execute(getRequest);
			final int statusCode = response.getStatusLine().getStatusCode();
			
			if (statusCode != HttpStatus.SC_OK) {
	            Log.w(Tag, "Error " + statusCode + " while retrieving bitmap from " + imageUrl);
	            return null;
	        }
			
			//取得相关信息 取得HttpEntiy
			HttpEntity entity = response.getEntity();
			if (entity != null) {
				inputStream = entity.getContent();
				long t2 = System.currentTimeMillis();
				Log.d(Tag, "图片: " + imageUrl + " | 耗时: " + (t2 - t1)/1000.000 + "秒");
				
				return inputStream;
			}
		} catch (Exception e) {
			getRequest.abort();
			Log.e(Tag, "I/O error while retrieving bitmap from " + imageUrl, e);
		}
		
		return null;
    }
	
    /**
     * 从SD卡缓存中取图片(返回Bitmap类型数据)
     * @since 2012/07/05 22:25
     * @param imageUrl
     * @return
     */
	private Bitmap getBitmapFromSDCache(String imageUrl) {
		Bitmap bitmap = null;
		File image = new File(cacheDir, getImageName(imageUrl));
		if (!image.exists()) return null;
		
		try {
			FileInputStream fileInputStream = new FileInputStream(image);
			bitmap = BitmapFactory.decodeStream(fileInputStream);
		} catch (FileNotFoundException e) {
			Log.e(Tag, "图片缓存不存在或已损坏");
			return null;
		}
		
		return bitmap;
	}
	
	/**
	 * 将图片存入SD卡中进行缓存
	 * @param imageUrl
	 * @param inputStream
	 */
	private void cacheToSdCard(String imageUrl, InputStream inputStream) {
		try {
			File storeFile = new File(cacheDir, getImageName(imageUrl));
			FileOutputStream fileOutputStream = new FileOutputStream(storeFile);
			byte[] buffer = new byte[4096];
			int count = 0;
			while ((count = inputStream.read(buffer)) != -1) {
				fileOutputStream.write(buffer, 0, count);
			}
			fileOutputStream.close();
			if (inputStream != null) inputStream.close();
		} catch (FileNotFoundException e) {
			Log.e(Tag, "保存缓存图片时发生错误", e);
		} catch (IOException e) {
			Log.e(Tag, "IO错误", e);
		}
	}
}
